package bot;

import client.MainViewJFrame;


/**
 * 
 * Controller of silly bot. Coordinate what to do. Subdivide work to other
 * components.
 * 
 * @author papq
 *
 * @version 0.1
 */
public class BotController implements Notificable {
	public BotModel model;
	private Core core;

	/**
	 * Method which allows controller to control other classes.
	 */
	public BotController(String host, int port) {
		this.model = new BotModel();
		this.core = new Core();

		model.setHost(host);
		model.setPort(port);
		System.out.println("Host: " + model.getHost());
		System.out.println("Port: " + model.getPort());
		
		try {
			core.connectToServer(model.getHost(), model.getPort());
			System.out.println("aaaa");
			model.setOperationCode(core.checkOperationCode());
			core.getMessage((Notificable) this);
			if (model.getOperationCode().equals("01")) {
				model.setParameters(core.getParameters());
				System.out.println("BotID: " + model.getPlayerID());
			}
			System.out.println(core.getMessageToDisplay());
		} catch (ConnectionFailureException e) {
			System.out.println("Connection Failure");
		}
	}
	
	public void Connect() {
		
	}

	/**
	 * Method which launch if server send message.
	 * 
	 * @param receivedMessage
	 *            content of message received from server.
	 */
	public void messageReceived(String receivedMessage) {
		try {
			core.getMessage((Notificable) this);
			model.setOperationCode(core.checkOperationCode(receivedMessage));

			System.out.println("(Msg from server) New received Message: " + receivedMessage);
			switch (model.getOperationCode()) {
			case "02":
				//asking player to start game
				System.out.println("(Msg from server) Asking to start: " + receivedMessage);
				if (receivedMessage.substring(8, 10).equals("ST")) {
					core.sendMessage("<" + model.getPlayerID() + "><02><Y>");
					System.out.println("SENDED TO SERVER: <" + model.getPlayerID() + "><02><Y>");
					System.out.println("Waiting for other players to start game.");
				} else {
					System.out.println("*** " + core.getMessageToDisplay());
				}
				break;
			case "03":
				System.out.println("(Msg from server) New hand: " + receivedMessage);
				model.setHand(core.getParameters());
				System.out.println("Cards exchanged. You have new card(s) now.");
				break;
			case "04":
				// Who has: dealer button, small blind, big blind
				System.out.println("(Msg from server) Setting dealer: " + receivedMessage);
				model.setDealer(receivedMessage.substring(8, 9));
				model.setWhoHasSmallBlind(receivedMessage.substring(10, 11));
				model.setWhoHasBigBlind(receivedMessage.substring(12, 13));
				model.setMaxBetNow(model.getBigBlind());
				break;
			case "05":
				// Betting
				System.out.println("(Msg from server) BettingRound: " + receivedMessage);
				switch(receivedMessage.substring(8, 10)) {
				case "ST":
					//betting round started
					model.setBettingRound(receivedMessage);
					System.out.println("BettingRound: " + model.getBettingRound());
					switch (model.getBettingRound()) {
					case "0":
						System.out.println("First betting round has started. Wait for your turn.");
						break;
					case "1":
						System.out.println("Second betting round has started. Wait for your turn.");
						break;
					case "2":
						System.out.println("Third betting round has started. Wait for your turn.");
						break;
					case "3":
						System.out.println("Last betting round has started. Wait for your turn.");
						break;
					}
					break;
				case "WD":
					//send bet option
					//model.setBettingRound(receivedMessage);
					switch (model.getBettingRound()) {
					case "0":
						System.out.println("First betting round. Choose option to bet.");
						if (model.getPlayerBankrollNow() < model.getMaxBetNow()) {
							core.sendMessage("<" + model.getPlayerID() + "><06><AL,0>");
							System.out.println("<" + model.getPlayerID() + "><06><AL,0>");
						} else {
							if (model.getPlayerBetNow() == model.getMaxBetNow()) {
								core.sendMessage("<" + model.getPlayerID() + "><06><CH,0>");
								System.out.println("<" + model.getPlayerID() + "><06><CH,0>");
							} else {
								core.sendMessage("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
								System.out.println("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
							}
						}
						break;
					case "1":
						System.out.println("Second betting round. Choose option to bet.");
						if (model.getPlayerBetNow() == model.getMaxBetNow()) {
							core.sendMessage("<" + model.getPlayerID() + "><06><CH,0>");
							System.out.println("<" + model.getPlayerID() + "><06><CH,0>");
						} else {
							core.sendMessage("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
							System.out.println("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
						}
						break;
					case "2":
						System.out.println("Third betting round. Choose option to bet.");
						if (model.getPlayerBetNow() == model.getMaxBetNow()) {
							core.sendMessage("<" + model.getPlayerID() + "><06><CH,0>");
							System.out.println("<" + model.getPlayerID() + "><06><CH,0>");
						} else {
							core.sendMessage("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
							System.out.println("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
						}
						break;
					case "3":
						System.out.println("Last betting round. Choose option to bet.");
						if (model.getPlayerBetNow() == model.getMaxBetNow()) {
							core.sendMessage("<" + model.getPlayerID() + "><06><CH,0>");
							System.out.println("<" + model.getPlayerID() + "><06><CH,0>");
						} else {
							core.sendMessage("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
							System.out.println("<" + model.getPlayerID() + "><06><CA," + model.getCallValue() +">");
						}
						break;
					}
					break;
				case "CH":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						System.out.println("*** You played \"Check\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"Check\".");
					}
					break;
				case "BE":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					model.setBetValueOfPlayerWhoPlayed(receivedMessage.split(",")[2]);
					model.setBankrollOfPlayerWhoPlayed(receivedMessage.split(",")[3]);
					model.setWasBetPlayed(true);
					if (model.getWhoHasSmallBlind().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())));
					} else if (model.getWhoHasBigBlind().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())));
					} else {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed()));
					}
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						if (model.getWhoHasSmallBlind().equals(model.getPlayerID())) {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())));
						} else if (model.getWhoHasBigBlind().equals(model.getPlayerID())) {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())));
						} else {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed()));
						}
						model.setPlayerBankrollNow(Integer.parseInt(model.getBankrollOfPlayerWhoPlayed()));
						System.out.println("*** You played \"Bet\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"Bet\".");
					}
					System.out.println("*** NEW MAX BET: " + model.getMaxBetNow());
					break;
				case "RA":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					model.setBetValueOfPlayerWhoPlayed(receivedMessage.split(",")[2]);
					model.setBankrollOfPlayerWhoPlayed(receivedMessage.split(",")[3]);
					model.setWasRaisePlayed(true);
					if (model.getWhoHasSmallBlind().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())));
					} else if (model.getWhoHasBigBlind().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())));
					} else {
						model.setMaxBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed()));
					}
					System.out.println("aaa NEW MAX BET: " + model.getMaxBetNow());
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						if (model.getWhoHasSmallBlind().equals(model.getPlayerID())) {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())));
						} else if (model.getWhoHasBigBlind().equals(model.getPlayerID())) {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())));
						} else {
							model.setPlayerBetNow(Integer.toString(model.getBetValueOfPlayerWhoPlayed()));
						}
						model.setPlayerBankrollNow(Integer.parseInt(model.getBankrollOfPlayerWhoPlayed()));
						System.out.println("*** You played \"Raise\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"Raise\".");
					}
					System.out.println("*** NEW MAX BET: " + model.getMaxBetNow());
					break;
				case "CA":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					model.setBankrollOfPlayerWhoPlayed(receivedMessage.split(",")[3]);
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setPlayerBetNow(Integer.toString(model.getMaxBetNow()));
						model.setPlayerBankrollNow(Integer.parseInt(model.getBankrollOfPlayerWhoPlayed()));
						System.out.println("*** You played \"Call\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"Call\".");
					}
					break;
				case "FO":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						System.out.println("*** You played \"Fold\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"Fold\".");
					}
					break;
				case "AL":
					model.setIDOfPlayerWhoPlayed(receivedMessage.substring(11, 12));
					model.setBetValueOfPlayerWhoPlayed(receivedMessage.split(",")[2]);
					if (model.getPlayerID().equals(model.getIDOfPlayerWhoPlayed())) {
						model.setPlayerBetNow(Integer.toString((model.getBetValueOfPlayerWhoPlayed()+model.getPlayerBetNow())));
						model.setPlayerBankrollNow(0);
						System.out.println("*** You played \"All-in\".");
					} else {
						System.out.println("*** Player " + model.getIDOfPlayerWhoPlayed() + " played \"All-in\".");
					}
					break;
				}
				break;
			case "07":
				//Changing - QUESTIONS of ROOM and messages of the ROOM.
				System.out.println("(Msg from server) Exchange: " + receivedMessage);
				switch(receivedMessage.substring(8, 10)) {
				case "ST":
					System.out.println("Card exchange has started. Wait for your turn.");
					break;
				case "WD":
					//bot turn to exchange cards
					model.setBotCardsToExchange();
					System.out.println("*** Your turn to exchange cards.");
					core.sendMessage("<" + model.getPlayerID() + "><08><" + model.getBotCardsToExchange() + ">");
					System.out.println("SENDED TO SERVER: <" + model.getPlayerID() + "><08><" + model.getBotCardsToExchange() + ">");
					model.forgetAboutSelection();
					break;
				default:
					//displays how many cards has another player changed
					model.setPlayerIDWhoExchanged(receivedMessage);
					model.setNrOfExchangedCards(receivedMessage);
					System.out.println("*** Player " + model.getPlayerIDWhoExchanged() + " has exchanged " + model.getNrOfExchangedCards() + "cards.");
				}
				break;
			case "09":
				//Winner announce.
				System.out.println("(Msg from server) Winner!: " + receivedMessage);
				switch(receivedMessage.substring(8, 10)) {
				case "WI":
					model.setNumberOfWinners(receivedMessage);
					model.setWinnerID(receivedMessage);
					model.setWinningAmount(receivedMessage);
					if (model.getWinnerID().equals(model.getPlayerID())) {
						model.setPlayerBankrollAfterWinning(Integer.parseInt(model.getWinningAmount()));
					}
					System.out.println("Winner!: Player " + model.getWinnerID() + " won " + model.getWinningAmount() + "T.");
					break;
				case "DR":
					//more than one winner
					model.setNumberOfWinners(receivedMessage);
					model.setWinnersID(receivedMessage);
					model.setWinningAmount(receivedMessage);
					for(int i=0; i<model.getNumberOfWinners(); i++){
						String winnerID = model.getWinnersID().substring(i, i+1);
						if(winnerID.equals(model.getPlayerID())) {
							model.setPlayerBankrollAfterWinning(Integer.parseInt(model.getWinningAmount()));
						}
					}
					System.out.println("Winners!: Players " + model.getWinnersID() + " won " + model.getWinningAmount() + "T.");
					break;
				}
				break;
			case "10":
				//next round?
				System.out.println("(Msg from server) Next round?: " + receivedMessage);
				switch(receivedMessage.substring(8, 10)) {
				case "AR":
					//yes, bot always want to play next round
					model.setModelToDefault();
					core.sendMessage("<0><10><Y>");
					System.out.println("SENDED TO SERVER: <0><10><Y>");
					break;
				case "LO":
					//sb loose. there won't be another game
					model.setLooserID(receivedMessage);
					System.out.println("Player " + model.getLooserID() + " have lost. Game over.");
					core.stopListen();
					System.out.println("Good bye!");
					System.exit(0);
					break;
				case "SN":
					//there won't be another game
					System.out.println("Other player(s) don't want to play anymore. Game over.");
					core.stopListen();
					System.out.println("Good bye!");
					System.exit(0);
					break;
				}
				break;
			case "30":
				//Errors
				System.out.println("(Msg from server) ERROR: " + receivedMessage);
				switch(receivedMessage.substring(8, 10)) {
				case "01":
					System.out.println("Bot, send this message once again, please.");
					break;
				case "02":
					System.out.println("EPIC FAILURE. Don't be afraid - the Server will create a new Room, and will be joined them automatically.");
					break;
				}
				break;
			}

		} catch (ConnectionFailureException e) {
			System.out.println("Connection Failure");
		}
	}

	/**
	 * Method which throws ConnectionFailureException from Thread
	 * serverListener.
	 */
	@Override
	public void connectionFailureExceptionOccured() {
		System.out.println("Thread serverListener interrupted.");
		// occurs always when we interrupt Thread
		// startView.informUserOfFailedConnection();
	}

	/**
	 * Method which throws NullPointerException from Thread serverListener.
	 */
	@Override
	public void nullPointerExceptionOccured() {
		System.out.println("Connection Failure - NullPointerException from Thread serverListener occured.");
	}
}
